package org.example.ai04.config;

import org.example.ai04.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Spring Security配置类
 * 负责配置应用程序的安全策略，包括认证、授权、会话管理等
 * 使用Spring Security 6.x配置方式，基于SecurityFilterChain和Lambda DSL
 * 配置了JWT认证、无状态会话、路径授权规则等安全特性
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 注入JWT认证过滤器
    // 用于拦截请求并验证JWT令牌
    @Autowired
    private JwtAuthenticationFilter jwtAuthFilter;

    /**
     * 创建密码编码器Bean
     * 使用BCrypt算法对密码进行加密和验证
     * BCrypt是一种自适应哈希函数，可以随着时间调整其工作因子
     * @return PasswordEncoder实例
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 创建认证管理器Bean
     * 负责处理认证请求，是Spring Security认证体系的核心组件
     * @param config 认证配置对象，包含认证相关的配置信息
     * @return AuthenticationManager实例，用于处理认证请求
     * @throws Exception 配置异常
     */
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    /**
     * 创建安全过滤器链Bean
     * 配置HTTP安全策略，包括CORS、CSRF、授权规则、会话管理等
     * 这是Spring Security 6.x的推荐配置方式，使用Lambda DSL
     * @param http HTTP安全构建器，用于配置各种安全策略
     * @return SecurityFilterChain实例，包含所有配置的安全过滤器
     * @throws Exception 配置异常
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 禁用CSRF保护
            // 在使用JWT的无状态API中通常禁用CSRF，因为JWT本身提供了安全机制
            .csrf(csrf -> csrf.disable())
            // 配置HTTP请求授权规则
            .authorizeHttpRequests(auth -> auth
                // 公开访问 - 模板页面：允许所有用户访问前端页面，前端通过JWT实现细粒度权限控制
                .requestMatchers("/", "/index.html", "/login.html", "/register.html", "/resume.html", "/admin.html").permitAll()
                // 公开访问 - 静态资源：允许所有用户访问CSS、JS、图片等静态资源，确保页面正常加载
                .requestMatchers("/css/**", "/js/**", "/images/**", "/static/**").permitAll()
                // API接口安全控制
                .requestMatchers("/api/auth/**").permitAll() // 认证相关API无需认证：登录、注册、刷新令牌等基础功能
                .requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理API需要ADMIN角色：数据统计、用户管理等管理功能
                .requestMatchers("/api/**").authenticated() // 其他API需要认证：确保已登录用户才能访问核心业务功能
                .anyRequest().permitAll() // 其他所有请求允许访问：兜底规则，确保未明确定义的请求不会被默认拒绝
            )
            // 配置会话管理策略为无状态
            // 无状态意味着服务器不会创建或使用会话来存储用户状态
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            // 禁用表单登录
            // 在使用JWT的应用中，通常使用自定义的认证端点
            .formLogin(form -> form.disable())
            // 禁用HTTP Basic认证
            // HTTP Basic认证在生产环境中不够安全
            .httpBasic(basic -> basic.disable())
            // 禁用登出功能
            // JWT认证通常不需要服务器端的登出机制
            .logout(logout -> logout.disable());
        
        // 添加JWT认证过滤器，放在UsernamePasswordAuthenticationFilter之前
        // 这样所有请求都会先经过JWT过滤器进行认证
        http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        
        // 构建并返回配置好的安全过滤器链
        return http.build();
    }
}